// DCMLicense.h: interface and implementation of the CDCMLicense class.
//
/////////////////////////////////////////////////////////////////////////////////
#ifndef __DCMLICENSE_H__
#define __DCMLICENSE_H__

#ifdef _XENON
#include <xtl.h>
#else
#include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include "time.h"

#include "../LIBTR/tr.h"
#include "DCMProductIds.h"
#include "license.h"
#include "utilprod.h"


class CDCMLicense  
{
public:
	enum
	{
		kTimeoutVal = 10 * 60 // 10 minutes
	};

	enum eLicenseAppType
	{	// used to initialize the module so that all licenses belong to a specific app
		 kLicAppTypeNone			=	0
		,kLicAppTypeWintube		=	1
	};

	enum eLicenseType
	{
		// apps
		// app should have been specified by SetApplication
		 kLicTypeApp			=	0	

		// filters
		,kLicTypeVideoEncoder	=	100
		,kLicTypeVideoDecoder	=	101
		,kLicTypeAudioEncoder	=	102
		,kLicTypeAudioDecoder	=	103
		,kLicTypeMux			=	104
		,kLicTypeDemux			=	105
		,kLicTypeAudioEffects	=	108
		,kLicTypeMp3Enc			=	109

		// features start at 150
	};

	inline CDCMLicense(eLicenseAppType appType, eLicenseType licType);
	inline CDCMLicense(eLicenseType type);
	inline CDCMLicense(eDCMProductId prodId);

	virtual ~CDCMLicense()
	{
		if(m_hRegReq)
		{
			CloseHandle(m_hRegReq);
			m_hRegReq = NULL;
		};
	}

#ifdef _NEW_OVERLOAD
    void *operator new( size_t stAllocateBlock)
	{
		LPVOID ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, stAllocateBlock);
		return ret;
	}
	void operator delete( void *pvMem )
	{
		HeapFree(GetProcessHeap(), 0, pvMem);
	}
#endif

	static  inline	DWORD	GetCustId(eLicenseAppType app);
	static  inline  DWORD	GetCustId();
 	static  inline	DWORD	GetVersion(eLicenseAppType app);
	static  inline	DWORD	GetVersion();
  	static  inline	DWORD	GetProductId(eLicenseAppType app);
	static  inline	DWORD	GetProductId();
	static	inline  time_t	GetTrialStartDate();
	static	inline  time_t	GetTrialStartDate(eLicenseType licType);
	static	inline  long	GetTrialDaysLeft();
	static	inline  long	GetTrialDaysLeft(eLicenseType licType);
	static	inline  void	SetTrialStartDate(time_t startDate);
	static	inline  void	SetTrialStartDate(eLicenseType licType, time_t startDate);
	static	inline	void	GetKeyString(char* pBuf, int bufLen, bool bWantUid);
	static	inline	void	GetKeyString(eLicenseAppType app, char* pBuf, int bufLen, bool bWantUid);
  	static  inline  long    GetKeyStringInfo(char* pBuf, USHORT* pId, USHORT* pVer, USHORT *pCust, DWORD *pOpts);
	static	inline	void	SetApplication(eLicenseAppType app);
	static	inline	HANDLE	SetRegRequired(eLicenseAppType app);
	virtual	inline  bool	CheckTrialPeriodElapsed(); // return true if 45 day trial has elapsed
	virtual	inline  bool	CheckTimeoutElapsed(); // return true if timeout (2-5 minutes) has elapsed
	static  inline  int		OpenOemLicense(DWORD oemId);
	static  inline  int		OpenOemLicense(eLicenseAppType app, DWORD oemId);
	bool					IsTrialVersion(){return (m_Options & kLicNoTimeout) ? false : true;}
	bool					IsEvalVersion(){return (m_Options & kLicNoExpiration) ? false : true;}
	bool					IsFullVersion(){return (!(IsEvalVersion()) && !(IsTrialVersion()));}
	bool					IsRegistered(){return (m_Options & kLicRegisterd) ? true :false;}
	bool					IsLiteVersion(){return (m_Options & kLicNotLite) ? false : true;}
    bool					IsProVersion(){return (m_Options & kLicProEdition) ? true : false;}

	bool					IsIPOD(){return false;}
	

	inline	int				GetInfo(CUTILprodinfo *info, BOOL bRecover=TRUE);
	inline	int				SetInfo(CUTILprodinfo *info);
	inline	DWORD			GetOptions() const;

	inline	int		SetOptions(DWORD opts);

	inline	void	SetExpired(bool bStat = true)
					{
								m_bLicViolatedU = bStat;
					}
	
	inline bool		IsExpired(){return m_bLicViolatedU || m_bLicViolated;}
	static inline	eLicenseAppType GetApplication();
	static inline	eDCMProductId	GetCurProdId(eLicenseAppType appType = kLicAppTypeNone);
	static inline	eLicenseAppType ProdId2AppType(eDCMProductId id);

	static inline	CUTILprod*		GetUtilProd(eLicenseAppType appType);
	static inline	CUTILprod*		GetUtilProd(eLicenseAppType appType, eLicenseType licType);

	inline void				GetApplicationName(TCHAR *cAppName);

	virtual inline HRESULT CheckLicense(unsigned __int64 CheckThis) const;
	virtual inline HRESULT CheckLicense(DWORD CheckThis) const;

protected:
	inline	bool	GetRegRequired();
	virtual inline void	InitLic(eLicenseAppType appType, eLicenseType licType);

	CDCMLicense(){}; // default ctor not allowed
	CDCMLicense(CDCMLicense& copy){} // copy ctor not allowed

	bool			m_bLicViolatedU; // for users to mark as violated
	bool			m_bLicViolated;  // for internal marking as violated
	time_t			m_StartTime;
	eLicenseAppType	m_AppType;
	HANDLE			m_hRegReq; // used to manage registration requirements

	DWORD			m_Options;

};



class CDCMLicense2 : public CDCMLicense
{
public:
	inline CDCMLicense2(eLicenseAppType appType, eLicenseType licType);
	inline CDCMLicense2(eLicenseType type);
	inline CDCMLicense2(eDCMProductId prodId);

	virtual bool				IsTrialVersion(){return (m_Options2 & kLicNoTimeout) ? false : true;}
	virtual bool				IsEvalVersion(){return (m_Options2 & kLicNoExpiration) ? false : true;}
	virtual bool				IsRegistered(){return (m_Options2 & kLicRegisterd) ? true :false;}
	virtual bool				IsLiteVersion(){return (m_Options2 & kLicNotLite) ? false : true;}
	virtual bool				IsProVersion(){return (m_Options2 & kLicProEdition) ? true : false;}
	virtual bool				IsIPOD(){return (m_Options2 & kLicIPOD) ? true : false;}

	inline	unsigned __int64 	GetOptions() const;
	virtual inline bool			CheckTrialPeriodElapsed();
	virtual inline bool			CheckTimeoutElapsed();
	inline	int					GetInfo(CUTILprodinfo2 *info, BOOL bRecover=TRUE);
	inline	int					SetInfo(CUTILprodinfo2 *info);

	static inline int			OpenOemLicense2(DWORD oemId);
	static inline int			OpenOemLicense2(eLicenseAppType app, DWORD oemId);

  	static  inline  long	GetKeyStringInfo(char* pBuf, USHORT* pId, USHORT* pVer, USHORT *pCust, unsigned __int64 *pOpts);

	virtual inline HRESULT CheckLicense(unsigned __int64 CheckThis) const;
	virtual inline void			GetApplicationName(TCHAR *cAppName);

protected:
	CDCMLicense2(){}; // default ctor not allowed
	CDCMLicense2(CDCMLicense& copy){} // copy ctor not allowed
	virtual inline void InitLic(eLicenseAppType appType, eLicenseType licType);

private:
	unsigned __int64		m_Options2;
	unsigned __int64		m_TrialOptions;
};


inline	unsigned __int64 CDCMLicense2::GetOptions() const
{
	return m_Options2;

}

inline HRESULT CDCMLicense::CheckLicense(DWORD CheckThis) const
{
	return m_Options & CheckThis ? S_OK : E_NOTIMPL;
}

inline HRESULT CDCMLicense::CheckLicense(unsigned __int64 CheckThis) const
{
	return m_Options & (DWORD)(0xffffffff & CheckThis) ? S_OK : E_NOTIMPL;
}

inline HRESULT CDCMLicense2::CheckLicense(unsigned __int64 CheckThis) const
{
	return m_Options2 & CheckThis ? S_OK : E_NOTIMPL;
}

inline void CDCMLicense2::InitLic(eLicenseAppType appType, eLicenseType licType)
{
	m_bLicViolated = false;
	m_bLicViolatedU = false;
	m_hRegReq = NULL;
	m_AppType = appType;
	m_Options2 = 0;

	m_StartTime = time(NULL);

	CUTILprod* pProd = GetUtilProd(m_AppType, licType);
	CUTILprod* pGProd = GetUtilProd(kLicAppTypeNone, licType); // getGenericProd

	eDCMProductId prodId = GetCurProdId(appType);
	
	if(pProd)
	{
		CUTILprodinfo2 prodinfo;
		int ret = 0;
		if(pProd->m_bUseNewLicense)
			ret = ((CUTILprod2*)pProd)->GetInfo(&prodinfo,FALSE);
		else
			ret = pProd->GetInfo(&prodinfo,FALSE);

		// try to see if there is old license in the system.
		if(ret!=0 && pProd->m_bUseNewLicense && m_AppType==kLicAppTypeNone)
		{
			 delete pProd;
			 pProd = GetUtilProd(m_AppType); // get GenericProd.
 			 ret = pProd->GetInfo(&prodinfo,FALSE);
		}


		// if the license does not match the product, then ignore it.
		//** WD: temp fix to enable GraphEdit
		// DR:  more temp to prevent license copying
		if(ret == 0 && (prodinfo.product == prodId || m_AppType == kLicAppTypeNone))
		{
			m_Options2 = prodinfo.option;
		}

//		if (m_AppType == kLicAppTypeWinDVDisdp && IsTrialVersion())
//		{
//			m_Options2 |= (kLicNoTimeout|kLicNoExpiration);
//			m_Options2 &= ~kLicAudDecAC3;
//		}

		//Preserve CPRM bit from GenericProd
		if (pGProd && ret == 0)
		{
			CUTILprodinfo2 gprodinfo;
			pGProd->GetInfo(&gprodinfo,FALSE);

		}
		delete pProd;
		delete pGProd;

		if(GetRegRequired() && (!(m_Options2 & kLicRegisterd)))
		{	// not registered.
			m_bLicViolated = true;
		}
		SetExpired(CheckTrialPeriodElapsed());
	}

}

// inline methods

inline	bool CDCMLicense2::CheckTrialPeriodElapsed()
{
	if(m_bLicViolated || m_bLicViolatedU)
		return true;

	if(!(m_Options2 & kLicNoExpiration))
	{

		CUTILprod* pProd = GetUtilProd(GetApplication());


		if(pProd && pProd->m_bUseNewLicense)
		{
			BOOL res = ((CUTILprod2*)pProd)->IsExpired();
			delete pProd;
			return res ? true : false;
		} else 	if(pProd) {
			BOOL res = pProd->IsExpired();
			delete pProd;
			return res ? true : false;
		}
		return true;
	}
	return false;
}


inline	bool CDCMLicense2::CheckTimeoutElapsed()
{
	if(m_bLicViolated || m_bLicViolatedU)
		return true;

	if(!(m_Options2 & kLicNoTimeout))
	{
		time_t cur = time(NULL);
		time_t delta = cur - m_StartTime;
		return delta > kTimeoutVal;
	}
	return false;
}

// inline methods
inline	bool CDCMLicense::CheckTrialPeriodElapsed()
{
	if(m_bLicViolated || m_bLicViolatedU)
		return true;

	if(!(m_Options & kLicNoExpiration))
	{
		CUTILprod* pProd = GetUtilProd(GetApplication());

		if(pProd)
		{
			BOOL res = pProd->IsExpired();
			delete pProd;
			return res ? true : false;
		}
			return true;
	}
	return false;
}


inline	bool CDCMLicense::CheckTimeoutElapsed()
{
	if(m_bLicViolated || m_bLicViolatedU)
		return true;

	if(!(m_Options & kLicNoTimeout))
	{
		time_t cur = time(NULL);
		time_t delta = cur - m_StartTime;
		return delta > kTimeoutVal;
	}
	return false;
}

inline	int CDCMLicense::GetInfo(CUTILprodinfo *pinfo , BOOL bRecover)
{
	int ret = -1;

	CUTILprod* pProd = GetUtilProd(m_AppType);

	if(pProd)
	{
		ret = pProd->GetInfo(pinfo,bRecover);
		delete pProd;
	}
	return ret;
}

inline	int CDCMLicense2::GetInfo(CUTILprodinfo2 *pinfo, BOOL bRecover)
{
	int ret = -1;
	CUTILprod* pProd = GetUtilProd(m_AppType);
	if(!pProd)
		return ret;

	if(pProd->m_bUseNewLicense)
	{
		ret = ((CUTILprod2*)pProd)->GetInfo(pinfo,bRecover);
		delete pProd;
	} 
	else 
	{
		CUTILprodinfo info;
		ret = pProd->GetInfo(&info,bRecover);
		pinfo->customer = info.customer;
		pinfo->option = (unsigned __int64) info.option;
		pinfo->product = info.product;
		pinfo->version = info.version;
		delete pProd;
	}
	return ret;
}

inline	int CDCMLicense::SetInfo(CUTILprodinfo *pinfo)
{
	int ret = -1;
	CUTILprod* pProd = GetUtilProd(m_AppType);
	if(pProd)
	{
		ret = pProd->SetInfo(pinfo);
		delete pProd;
	}
	return ret;
}

inline	int CDCMLicense2::SetInfo(CUTILprodinfo2 *pinfo)
{
	int ret = -1;
	CUTILprod* pProd = GetUtilProd(m_AppType);
	if(!pProd)
		return ret;

	if(pProd->m_bUseNewLicense)
	{
		ret = pProd->SetInfo(pinfo);
	}
	else
	{
		CUTILprodinfo info;
		info.customer = pinfo->customer;
		info.option =(DWORD) pinfo->option;
		info.product = pinfo->product;
		info.version = pinfo->version;
		ret = pProd->SetInfo(pinfo);
	}
	delete pProd;
	return ret;
}


inline	DWORD	CDCMLicense::GetOptions() const
{
	return m_Options;
}

inline	int CDCMLicense::SetOptions(DWORD opts)
{
	int ret = -1;
	CUTILprod* pProd = GetUtilProd(m_AppType);
	if(pProd)
	{
		CUTILprodinfo prodinfo;
		ret = pProd->GetInfo(&prodinfo);

		if(ret == 0 && (prodinfo.product == GetCurProdId(m_AppType) || m_AppType == kLicAppTypeNone))
		{
			prodinfo.option |= opts;
			ret = pProd->SetInfo(&prodinfo);
		}
		else
			ret = -1;
		delete pProd;
	}
	return ret;
}

inline	CUTILprod* CDCMLicense::GetUtilProd(eLicenseAppType appType)
{
	return GetUtilProd(appType, kLicTypeApp);
}

inline CUTILprod* CDCMLicense::GetUtilProd(eLicenseAppType appType, eLicenseType licType)
{
	CUTILprod* pProd = NULL;
	switch(appType)
	{
		case kLicAppTypeWintube:
			pProd = new CUTILProdWintube(HKEY_CLASSES_ROOT, LIC_REGISTRY);
			break;
		default : // use generic license
			pProd = new CUTILprodGeneric2(HKEY_CLASSES_ROOT, LIC_REGISTRY);
			break;
	}

	return pProd;
}


inline CDCMLicense::eLicenseAppType CDCMLicense::ProdId2AppType(eDCMProductId id)
{
	switch(id)
	{
		case kProdIdWinTube:  // :
			return kLicAppTypeWintube;
		default:
			return kLicAppTypeNone;
	}
}

inline eDCMProductId CDCMLicense::GetCurProdId(eLicenseAppType appType)
{

	eDCMProductId prodId = kProdIDNone;

	if(appType == kLicAppTypeNone)
		appType = GetApplication();
	switch(appType)
	{
		case kLicAppTypeWintube:
			prodId = kProdIdWinTube; 
			break;

		default : // use generic license
			break;
	}

	return prodId;
}


void CDCMLicense::SetTrialStartDate(time_t startDate)
{
	CUTILprod* pProd = GetUtilProd(GetApplication());
	if(pProd)
	{
		pProd->SetTrialStartDate(startDate);
		delete pProd;
	}
}

time_t CDCMLicense::GetTrialStartDate(eLicenseType licType)
{
	time_t startDate = 0;

	eLicenseAppType app = GetApplication();

	CUTILprod* pProd = GetUtilProd(app, licType);

	if(pProd)
	{
		startDate = pProd->GetTrialStartDate();
		delete pProd;
	}
	return startDate;
}

time_t CDCMLicense::GetTrialStartDate()
{
	return GetTrialStartDate(kLicTypeApp);
}

long CDCMLicense::GetTrialDaysLeft(eLicenseType licType)
{
	eLicenseAppType app = GetApplication();

	CUTILprod* pProd = GetUtilProd(app, licType);

	if(pProd)
	{
		time_t trialDaysLeft = pProd->GetTrialTimeLeft();
		delete pProd;
		return (long)trialDaysLeft;
	}
	return 0;
}

long CDCMLicense::GetTrialDaysLeft()
{
	return GetTrialDaysLeft(kLicTypeApp);
}

DWORD CDCMLicense::GetCustId()
{
	return GetCustId(GetApplication());
}

DWORD CDCMLicense::GetCustId(eLicenseAppType app)
{
	CUTILprod* pProd = GetUtilProd(app);
	if(pProd)
	{
		DWORD CustomerID;
		CUTILprodinfo prodinfo;
		int ret = pProd->GetInfo(&prodinfo,FALSE);
		CustomerID = ret==0 ? prodinfo.customer : 0;
		delete pProd;

		return CustomerID;
	}

	return 0;
}

DWORD CDCMLicense::GetVersion()
{
	return GetVersion(GetApplication());
}

DWORD CDCMLicense::GetVersion(eLicenseAppType app)
{
	// temp code using CUTILprod to get app options (hard coded to WinDVR)
	CUTILprod* pProd = GetUtilProd(app);

	if(pProd)
	{
		DWORD ver;
		CUTILprodinfo prodinfo;
		int ret = pProd->GetInfo(&prodinfo,FALSE);
		ver = ret==0 ? prodinfo.version : 0;
		delete pProd;

		return ver;
	}

	return 0;

}

DWORD CDCMLicense::GetProductId()
{
	return GetProductId(GetApplication());
}

DWORD CDCMLicense::GetProductId(eLicenseAppType app)
{
	// temp code using CUTILprod to get app options (hard coded to WinDVR)


	CUTILprod* pProd = GetUtilProd(app);

	if(pProd)
	{
		DWORD prodId;
		CUTILprodinfo prodinfo;
		int ret = pProd->GetInfo(&prodinfo,FALSE);
		prodId = ret==0 ? prodinfo.product : 0;
		delete pProd;
		return prodId;
	}

	return 0;

}

void CDCMLicense::GetKeyString(char* pBuf, int bufLen, bool bWantUid)
{
	GetKeyString(GetApplication(), pBuf, bufLen, bWantUid);
}

void CDCMLicense::GetKeyString(eLicenseAppType appType, char* pBuf, int bufLen, bool bWantUid)
{
	if (pBuf==0 || bufLen==0)
		return;

	// temp code using CUTILprod to get app options (hard coded to WinDVR)
	CUTILprod* pProd = GetUtilProd(appType);

	if(pProd)
	{
		if(pProd->m_bUseNewLicense)
		{
			CUTILprodinfo2 prodinfo;
			int ret = pProd->GetInfo(&prodinfo);
			if (ret == 0)
				{
				if(bWantUid)
					pProd->InfoToText(&prodinfo, pBuf, bufLen);	
				else
					strncpy(pBuf, prodinfo.key, bufLen);
				}
			else
				*pBuf=0;
		} else {
			CUTILprodinfo2 prodinfo;
			int ret = pProd->GetInfo(&prodinfo);
			if (ret == 0)
				{
				if(bWantUid)
					pProd->InfoToText(&prodinfo, pBuf, bufLen);	
				else
					strncpy(pBuf, prodinfo.key, bufLen);
				}
			else
				*pBuf=0;
		}

		delete pProd;
	}
}

long CDCMLicense::GetKeyStringInfo(char* pBuf, USHORT* pId, USHORT* pVer, USHORT *pCust, DWORD *pOpts)
{
	CUTILprodinfo pi;
	CUTILprod prod;
	DWORD key;
	*pId = *pVer = *pCust = 0;
	*pOpts = 0;
	if(prod.TextToInfo(&pi, &key, pBuf) == 0)
	{
		*pId = pi.product;
		*pVer = pi.version;
		*pCust = pi.customer;
		*pOpts = pi.option;
		return 0;
	}
	return -1;
}

long CDCMLicense2::GetKeyStringInfo(char* pBuf, USHORT* pId, USHORT* pVer, USHORT *pCust, unsigned __int64 *pOpts)
{
	CUTILprodinfo2 pi;
	CUTILprod2 prod;
	DWORD key;
	*pId = *pVer = *pCust = 0;
	*pOpts = 0;
	if(prod.TextToInfo(&pi, &key, pBuf) == 0)
	{
		*pId = pi.product;
		*pVer = pi.version;
		*pCust = pi.customer;
		*pOpts = pi.option;
		return 0;
	}
	return -1;
}



inline int CDCMLicense2::OpenOemLicense2(DWORD oemId)
{
	eLicenseAppType app = GetApplication();
	return OpenOemLicense2(app, oemId);

}

inline int CDCMLicense2::OpenOemLicense2(eLicenseAppType app, DWORD oemId)
{
	CUTILprod* pProd = GetUtilProd(app);

	if(pProd == NULL)
		return -1;
	int ret = -1;

	if(pProd->m_bUseNewLicense)
	{
		CUTILprodinfo2 prodinfo;
		ret = ((CUTILprod2 *)pProd)->GetInfo(&prodinfo,FALSE);
		if(ret < 0 || prodinfo.customer != oemId)
		{ // try oem crack
			ret = ((CUTILprod2 *)pProd)->OpenOemLicense(&prodinfo, oemId);
			if(ret == 0)
				pProd->SetInfo(&prodinfo);
		}
	} else {
		CUTILprodinfo prodinfo;
		ret = pProd->GetInfo(&prodinfo,FALSE);
		if(ret < 0 || prodinfo.customer != oemId)
		{ // try oem crack
			ret = pProd->OpenOemLicense(&prodinfo, oemId);
			if(ret == 0)
				pProd->SetInfo(&prodinfo);
		}
	}


	delete pProd;

	return ret;

}


inline int CDCMLicense::OpenOemLicense(DWORD oemId)
{
	eLicenseAppType app = GetApplication();
	return OpenOemLicense(app, oemId);

}

inline int CDCMLicense::OpenOemLicense(eLicenseAppType app, DWORD oemId)
{
	CUTILprod* pProd = NULL;


	CUTILprodinfo prodinfo;
	int ret;

	if(app == kLicAppTypeNone)
		pProd = new CUTILprodGeneric(HKEY_CLASSES_ROOT, LIC_REGISTRY);
	else
		pProd = GetUtilProd(app);

	if(pProd == NULL)
		return -1;

	ret = pProd->GetInfo(&prodinfo);
	if(ret < 0 || prodinfo.customer != oemId)
	{ // try oem crack
		ret = pProd->OpenOemLicense(&prodinfo, oemId);
		if(ret == 0)
			pProd->SetInfo(&prodinfo);
	}

	delete pProd;

	return ret;

}

inline CDCMLicense::CDCMLicense(eLicenseType licType)
{
	eLicenseAppType appType = GetApplication();
	InitLic(appType, licType);
}

inline CDCMLicense::CDCMLicense(eDCMProductId prodId)
{
	eLicenseAppType appType = ProdId2AppType(prodId);
	InitLic(appType, kLicTypeApp);
}

inline CDCMLicense::CDCMLicense(eLicenseAppType appType, eLicenseType licType)
{
	InitLic(appType, licType);
}


inline CDCMLicense2::CDCMLicense2(eLicenseType licType)
{
	eLicenseAppType appType = GetApplication();
	InitLic(appType, licType);
}

inline CDCMLicense2::CDCMLicense2(eDCMProductId prodId)
{
	eLicenseAppType appType = ProdId2AppType(prodId);
	InitLic(appType, kLicTypeApp);
}

inline CDCMLicense2::CDCMLicense2(eLicenseAppType appType, eLicenseType licType)
{
	InitLic(appType, licType);
}

inline void CDCMLicense::InitLic(eLicenseAppType appType, eLicenseType licType)
{
	m_bLicViolated = false;
	m_bLicViolatedU = false;
	m_hRegReq = NULL;
	m_AppType = appType;
	m_Options = 0;

	m_StartTime = time(NULL);

	CUTILprod* pProd = GetUtilProd(m_AppType, licType);
	eDCMProductId prodId = GetCurProdId(appType);

	if(pProd)
	{
		CUTILprodinfo prodinfo;
		int ret = pProd->GetInfo(&prodinfo,FALSE);

		// if the license does not match the product, then ignore it.
		//** WD: temp fix to enable GraphEdit
		// DR:  more temp to prevent license copying
		if(ret == 0 && (prodinfo.product == prodId || m_AppType == kLicAppTypeNone))
			m_Options = prodinfo.option;
//		if (m_AppType == kLicAppTypeWinDVDisdp && IsTrialVersion())
//		{
//			m_Options |= (kLicNoTimeout|kLicNoExpiration);
//			m_Options &= ~kLicAudDecAC3;
//		}
		delete pProd;

		if(GetRegRequired() && (!(m_Options & kLicRegisterd)))
		{	// not registered.
			m_bLicViolated = true;
		}
		SetExpired(CheckTrialPeriodElapsed());
	}

}


#define APP_FMT_STR _T("__@@70AA37E1_6D4D_11d4_A90B_0050DACE2436_%x")
inline	void CDCMLicense::SetApplication(eLicenseAppType app)
{
	TCHAR valBuf[32];
	_stprintf(valBuf, _T("%d"), app);

	SetEnvironmentVariable(APP_FMT_STR, valBuf);

}

inline CDCMLicense::eLicenseAppType CDCMLicense::GetApplication()
{
	TCHAR valBuf[32];
	
	if(GetEnvironmentVariable(APP_FMT_STR, valBuf, 32) > 0)
	{  
		return (CDCMLicense::eLicenseAppType) _ttol(valBuf);
	}

	return kLicAppTypeNone;

}

#define REG_FMT_STR _T("%s%08lX_%04lX_%04lX_%04lX_%08lX%04lX_%X")
//_T("__@@845921FF_6D4D_11d4_DE39_003EBDCF5968_%08X%X")

// if reg is required, then we will create a mutex.  The presence of the mutex means that 
// we enforce registration
inline	HANDLE CDCMLicense::SetRegRequired(eLicenseAppType app)
{
	TCHAR buf[128];

	DWORD procId = GetCurrentProcessId();
	DWORD dword1 = (procId <<16) | (procId ^ 0x0000badd);
	DWORD dword2 = (procId <<14) | (procId ^ 0x1a22b3c4);
	DWORD word1  = LOWORD((procId << 8) | (procId ^ 0x1234));
	DWORD word2  = LOWORD((procId << 6) | (procId ^ 0xFEDC));
	DWORD word3  = LOWORD((procId << 6) | (procId ^ 0xA9F1));
	DWORD word4  = LOWORD((procId << 4) | (procId ^ 0x5C9D));
	_stprintf(buf, REG_FMT_STR, _T("__@@"), dword1, word1, word2, word3, dword2, word4, app);
	HANDLE hRegReq = CreateMutex(NULL, FALSE, buf);

	return hRegReq;
}

inline bool CDCMLicense::GetRegRequired()
{
	if(!m_hRegReq)
	{
		TCHAR buf[128];
		eLicenseAppType app = GetApplication();
		DWORD procId = GetCurrentProcessId();
		DWORD dword1 = (procId <<16) | (procId ^ 0x0000badd);
		DWORD dword2 = (procId <<14) | (procId ^ 0x1a22b3c4);
		DWORD word1  = LOWORD((procId << 8) | (procId ^ 0x1234));
		DWORD word2  = LOWORD((procId << 6) | (procId ^ 0xFEDC));
		DWORD word3  = LOWORD((procId << 6) | (procId ^ 0xA9F1));
		DWORD word4  = LOWORD((procId << 4) | (procId ^ 0x5C9D));
		_stprintf(buf, REG_FMT_STR, _T("__@@"), dword1, word1, word2, word3, dword2, word4, app);
#if defined(_WIN32) && !defined(_XENON)
		OSVERSIONINFO osvi;
		osvi.dwOSVersionInfoSize = sizeof(osvi);
		BOOL bWin9x = GetVersionEx(&osvi) && osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS;
#else
		BOOL bWin9x = 0;
#endif
		m_hRegReq = OpenMutex(bWin9x ? MUTEX_ALL_ACCESS : SYNCHRONIZE, FALSE, buf);
	}
			
	return m_hRegReq  ? true : false;
}

inline void CDCMLicense2::GetApplicationName(TCHAR* cAppName)
{
	static struct ApplicationName
	{
		USHORT	usAppType;
		LPCTSTR	szAppName;
	} g_ApplicationNameTable[] = 
	{
		{CDCMLicense::kLicAppTypeNone			, TEXT("Generic Application")		},
		{CDCMLicense::kLicAppTypeWintube			, TEXT("Wintube")					},
	};
	
	eLicenseAppType appType = GetApplication();

	for (size_t i = 0; 
		 i < sizeof(g_ApplicationNameTable)/sizeof(g_ApplicationNameTable[0]);
		 ++i)
	{
		if (appType == (g_ApplicationNameTable[i].usAppType)) 
		{
			_tcscpy(cAppName, g_ApplicationNameTable[i].szAppName);
			break;
		}
	}
}

#endif 
